package com.shanzhu.volunteer.modules.volunteer.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.shanzhu.volunteer.common.config.ProjectConfig;
import com.shanzhu.volunteer.common.core.LambdaQueryWrapperX;
import com.shanzhu.volunteer.common.exception.ServiceException;
import com.shanzhu.volunteer.common.exception.file.FileSizeLimitExceededException;
import com.shanzhu.volunteer.common.utils.SecurityUtil;
import com.shanzhu.volunteer.common.utils.file.FileUploadUtil;
import com.shanzhu.volunteer.common.utils.file.MimeTypeUtils;
import com.shanzhu.volunteer.interfaces.vo.volunteer.comment.CampusFileVo;
import com.shanzhu.volunteer.interfaces.vo.volunteer.comment.FileVo;
import com.shanzhu.volunteer.modules.volunteer.entity.enums.CampusBizCodeEnum;
import com.shanzhu.volunteer.modules.volunteer.entity.model.CampusFileEntity;
import com.shanzhu.volunteer.modules.volunteer.entity.model.FileEntity;
import com.shanzhu.volunteer.modules.volunteer.mapper.CampusFileMapper;
import com.shanzhu.volunteer.modules.volunteer.service.CampusFileService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 *
 */
@Service
public class CampusFileServiceImpl extends ServiceImpl<CampusFileMapper, CampusFileEntity>
        implements CampusFileService {

    /**
     * 文章图片文件起始路径
     */
    private static String CAMPUS_CONTENT_FILE_PATH = ProjectConfig.getContentPath();

    /**
     * 文章视频文件起始路径
     */
    private static String CAMPUS_VIDEO_FILE_PATH = ProjectConfig.getVideoPath();

    /**
     * 文件当日最大上传数量
     */
    private static final int FILE_MAX_COUNT_DAY = 50;

    /**
     * 图片最大为5M
     */
    private static final int IMAGE_MAX_SIZE = 5 * 1024 * 1024;

    /**
     * 视频最大为20M
     */
    private static final int VIDEO_MAX_SIZE = 20 * 1024 * 1024;

    @Autowired
    private CampusFileMapper campusFileMapper;

    @Override
    public List<CampusFileVo> getContentFile(List<Long> contentId) {
        List<CampusFileEntity> campusFileEntities = campusFileMapper.selectList(
                new LambdaQueryWrapperX<CampusFileEntity>().in(CampusFileEntity::getContentId, contentId));

        //根据id,把url相放入前面的集合
        List<CampusFileEntity> collect = campusFileEntities.stream().collect(
                Collectors.toMap(CampusFileEntity::getContentId, a -> a, (o1, o2) -> {
                    List<String> fileUrl = o1.getFileUrls();
                    if (fileUrl.size() == 0) {
                        fileUrl.add(o1.getUrl());
                    }
                    fileUrl.add(o2.getUrl());
                    return o1;
                })).values().stream().collect(Collectors.toList());
        //转集合
        List<CampusFileVo> CampusFileVoList = collect.stream().map(CampusFileVo::new).collect(Collectors.toList());


        return CampusFileVoList;
    }

    @Override
    public CampusFileVo getContentFile(Long contentId) {
        return campusFileMapper.getContentFile(contentId);
    }

    @Override
    public CampusFileEntity fileUploadImage(MultipartFile file) {
        assertAllowed();
        if (file.getSize() > IMAGE_MAX_SIZE) {
            throw new FileSizeLimitExceededException(IMAGE_MAX_SIZE / 1024 / 1024);
        }
        try {
            String path = FileUploadUtil.upload(CAMPUS_CONTENT_FILE_PATH, file, MimeTypeUtils.IMAGE_EXTENSION);
            return saveDB(path, file.getOriginalFilename());
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(e.getMessage());
        }

    }

    @Override
    public CampusFileEntity fileUploadVideo(MultipartFile file) {
        assertAllowed();
        if (file.getSize() > VIDEO_MAX_SIZE) {
            throw new FileSizeLimitExceededException(VIDEO_MAX_SIZE / 1024 / 1024);
        }
        try {
            String path = FileUploadUtil.upload(CAMPUS_VIDEO_FILE_PATH, file, MimeTypeUtils.VIDEO_EXTENSION);
            return saveDB(path, file.getOriginalFilename());
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(e.getMessage());
        }

    }

    @Override
    public int updateContentFile(List<FileVo> files, Long contentId) {
        if (files != null && files.size() > 0) {
            for (FileVo file : files) {
                if (file.getFileId() == null) {
                    continue;
                }
                CampusFileEntity entity = this.getById(file.getFileId());

                entity.setContentId(contentId);
                entity.setFileName(file.getFileName());
                //去掉/dev-api前缀
                String changedUrl = StringUtils.removeStart(file.getFileUrl(), "/dev-api");
                entity.setUrl(changedUrl);

                this.updateById(entity);
            }
//            return campusFileMapper.updateContentFile(files, contentId);
        } else {
            return 0;
        }

        return 1;

    }

    @Override
    public boolean fileExist(List<Long> files, int type) {
        if (files.size() == 0) {
            return false;
        }
        Long count = campusFileMapper.selectCount(new LambdaQueryWrapperX<CampusFileEntity>()
                .in(CampusFileEntity::getFileId, files).isNull(CampusFileEntity::getContentId));
        return count == files.size();
    }

    @Override
    public void removeCampusFile(Integer type) {
        List<CampusFileEntity> fileList = campusFileMapper.getNoContentFileList();

        fileList.forEach(i -> {
            String filePath = i.getUrl();
            if (filePath.startsWith("/profile")) {

                // 4、切割文件名
                String fileUuidName = i.getUrl().substring(i.getUrl().lastIndexOf("/") + 1);

                // 4. 从文件系统删除文件 类型：0文字,1图片,2视频
                Path filePath1 = Paths.get(type == 1 ? CAMPUS_CONTENT_FILE_PATH : CAMPUS_VIDEO_FILE_PATH).resolve(fileUuidName);

                File file = new File(filePath1.toString());
                if (file.isFile() && file.exists()) {
                    campusFileMapper.deleteById(i.getFileId());

                    try {
                        Files.deleteIfExists(filePath1);
                    } catch (IOException e) {
                        throw new ServiceException(CampusBizCodeEnum.DELETE_FILE_ERROR.getMsg(),
                                CampusBizCodeEnum.DELETE_FILE_ERROR.getCode()); // 删除文件失败
                    }
                }
            }

        });
    }

    @Override
    @Transactional
    public void deleteFile(Long fileId, String fileName, int type) {
        // 1. 验证文件存在性
        CampusFileEntity campusFileEntity = campusFileMapper.selectOne(new LambdaQueryWrapperX<CampusFileEntity>()
                .eq(CampusFileEntity::getFileId, fileId));
        if (campusFileEntity == null) {
            throw new RuntimeException("文件不存在");
        }

        if (fileName == null && campusFileEntity.getFileName() == null) {
            // 3. 从数据库删除记录
            campusFileMapper.deleteById(fileId);

            // 4、切割文件名
            String fileUuidName = campusFileEntity.getUrl().substring(campusFileEntity.getUrl().lastIndexOf("/") + 1);

            // 4. 从文件系统删除文件 类型：0文字,1图片,2视频
            Path filePath = Paths.get(type == 1 ? CAMPUS_CONTENT_FILE_PATH : CAMPUS_VIDEO_FILE_PATH).resolve(fileUuidName);
            try {
                Files.deleteIfExists(filePath);
            } catch (IOException e) {
                throw new ServiceException(CampusBizCodeEnum.DELETE_FILE_ERROR.getMsg(),
                        CampusBizCodeEnum.DELETE_FILE_ERROR.getCode()); // 删除文件失败
            }
            return;
        }

        // 2. 验证文件名匹配
        if (!campusFileEntity.getFileName().equals(fileName)) {
            throw new RuntimeException("文件名不匹配");
        }

        // 3. 从数据库删除记录
        campusFileMapper.deleteById(fileId);

        // 4、切割文件名
        String fileUuidName = campusFileEntity.getUrl().substring(campusFileEntity.getUrl().lastIndexOf("/") + 1);

        // 4. 从文件系统删除文件 类型：0文字,1图片,2视频
        Path filePath = Paths.get(type == 1 ? CAMPUS_CONTENT_FILE_PATH : CAMPUS_VIDEO_FILE_PATH).resolve(fileUuidName);
        try {
            Files.deleteIfExists(filePath);
        } catch (IOException e) {
            throw new ServiceException(CampusBizCodeEnum.DELETE_FILE_ERROR.getMsg(),
                    CampusBizCodeEnum.DELETE_FILE_ERROR.getCode()); // 删除文件失败
        }
    }

    /**
     * 文件是否允许上传
     */
    private void assertAllowed() {

        long countDay = campusFileMapper.getFileCountDay(SecurityUtil.getUserId());

        if (countDay >= FILE_MAX_COUNT_DAY) {
            throw new ServiceException(CampusBizCodeEnum.TOO_MANY_File.getMsg(),
                    CampusBizCodeEnum.TOO_MANY_File.getCode());
        }
    }

    /**
     * 保存文件信息到数据库
     */
    private CampusFileEntity saveDB(String path, String fileName) {
        CampusFileEntity campusFileEntity = new CampusFileEntity();
//        campusFileEntity.setFileId(IdWorker.getId());
//        long id = (long) (Math.random() * 1000000);
        campusFileEntity.setFileId(System.currentTimeMillis());
        campusFileEntity.setUserId(SecurityUtil.getUserId());
        campusFileEntity.setUrl(path);
        campusFileEntity.setFileName(fileName);
        campusFileEntity.setCreateTime(new Date());
        campusFileMapper.insert(campusFileEntity);
        return campusFileEntity;
    }
}




